package com.xiaopeng.common.enumUtil;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Objects;

/**
 * 枚举转换序列化
 * @author xiaopeng
 */
@Slf4j
public class EnumViewSerialize extends JsonSerializer<Object> implements ContextualSerializer {

    // 转换枚举的新字段后缀名
    private static final String FIELD_SUFFIX = "Desc";

    private EnumView enumView;

    public EnumViewSerialize() {}

    public EnumViewSerialize(EnumView enumView) {
        this.enumView = enumView;
    }

    /**
     * 选择对应的序列化
     *
     * @return
     * @throws JsonMappingException
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        EnumView enumView = property.getAnnotation(EnumView.class);
        if (Objects.nonNull(enumView)) {
            // 直接返回this enumView会给覆盖
            return new EnumViewSerialize(enumView);
        }
        return prov.findValueSerializer(property.getType(), property);
    }

    /**
     * 序列化处理
     */
    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeObject(value);
        // 创建desc字段 对字段进行枚举值转换
        String newFieldName = null;
        String className = null;
        try {
            JsonStreamContext outputContext = gen.getOutputContext();
            className = outputContext.getCurrentValue().getClass().getName();
            String fieldName = gen.getOutputContext().getCurrentName();
            newFieldName = fieldName + FIELD_SUFFIX;
            gen.writeStringField(newFieldName, EnumViewHandler.getNameByCode(this.enumView, value));
        } catch (Exception e) {
            gen.writeStringField(newFieldName, e.getMessage());
            log.error("Json转换-获取枚举转换异常 映射字段:{}:{} 异常;{}", className, newFieldName, e.getMessage(), e);
        }
    }

}
